package com.study.xml.junit;

import java.io.FileOutputStream;
import java.io.OutputStream;

import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.XPath;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;
import org.junit.Test;

import com.study.xml.utils.DOM4JUtils;

/**
* @Name: DOM4JXpathTest
* @Description:	使用DOM4J解析XML测试类，使用Xpath语法定位元素位置
* @Author: 李超	lc_jack@foxmail.com
* @CreateDate: 2017-2-26 下午2:29:59 
* @Version: V1.0
 */
public class DOM4JXpathTest {
	
	/**
	* @Name: writeXML2Console
	* @Description: 将指定XML文件中的内容打印到控制台
	* @Author: 李超	lc_jack@foxmail.com
	* @Version: V1.0
	* @CreateDate: 2017-2-26 下午4:14:20
	* @Parameters: 
	* @Return: void
	 */
	@Test
	public void writeXML2Console() throws Exception {
		SAXReader reader = new SAXReader() ;
		String url = "src/books.xml" ;
		Document document = reader.read(url) ;
		OutputFormat format = OutputFormat.createPrettyPrint() ;
		XMLWriter writer = new XMLWriter(System.out, format) ;
		writer.write(document) ;
	}
	
	/**
	* @Name: findElementContent
	* @Description: 得到某个具体节点的内容
	* 例如：
	* 	得到第二本书节点中的售价节点的内容
	* @Author: 李超	lc_jack@foxmail.com
	* @Version: V1.0
	* @CreateDate: 2017-2-26 下午4:17:35
	* @Parameters: 
	* @Return: void
	 */
	@Test
	public void findElementContent() throws Exception {
		SAXReader reader = new SAXReader() ;
		String url = "src/books.xml" ;
		Document document = reader.read(url) ;
		Node salePrice = document.selectSingleNode("/书架/书[2]/售价") ;
		System.out.println(salePrice.getUniquePath() + "[" + salePrice.getText() + "]");
	}
	
	/**
	* @Name: iteratorAllElement
	* @Description: 遍历所有元素节点
	* @Author: 李超	lc_jack@foxmail.com
	* @Version: V1.0
	* @CreateDate: 2017-2-26 下午4:22:46
	* @Parameters: 
	* @Return: void
	 */
	@Test
	public void iteratorAllElement() throws Exception {
		SAXReader reader = new SAXReader() ;
		String url = "src/books.xml" ;
		Document document = reader.read(url) ;
		Element rootElement = document.getRootElement() ;
		treeWalk(rootElement) ;
	}
	
	private void treeWalk(Element element) {
		System.out.println(element.getName());
		for (int i = 0; i < element.nodeCount(); i++) {
			Node node = element.node(i) ;
			if(node instanceof Element) {
				treeWalk((Element) node) ;
			}
		}
	}
	
	/**
	* @Name: updateElementContent
	* @Description: 修改某个元素节点下的内容
	* 例如：
	* 	修改第二本书节点下售价节点的内容为300
	* @Author: 李超	lc_jack@foxmail.com
	* @Version: V1.0
	* @CreateDate: 2017-2-26 下午4:27:04
	* @Parameters: 
	* @Return: void
	 */
	@Test
	public void updateElementContent() throws Exception {
		SAXReader reader = new SAXReader() ;
		String url = "src/books.xml" ;
		Document document = reader.read(url) ;
		Element salePrice = (Element) document.selectSingleNode("/书架/书[2]/售价") ;
		salePrice.setText("300") ;
		OutputStream out = new FileOutputStream(url) ;
		OutputFormat format = OutputFormat.createPrettyPrint() ;
		format.setEncoding("UTF-8") ;
		XMLWriter writer = new XMLWriter(out, format) ;
		writer.write(document) ;
	}
	
	/**
	* @Name: addChildElement
	* @Description: 向指定元素节点增加子节点
	* 例如：
	* 	向第二本书节点的售价前增加内部价：<批发价 id="p2" name="pfj">800</批发价>  
	* @Author: 李超	lc_jack@foxmail.com
	* @Version: V1.0
	* @CreateDate: 2017-2-26 下午4:30:40
	* @Parameters: 
	* @Return: void
	 */
	@Test
	public void addChildElement() throws Exception {
		String url = "src/books.xml" ;
		Document document = DOM4JUtils.getDocument(url) ;
		Element secondBook = (Element) document.selectSingleNode("//书[2]") ;
		secondBook.addElement("批发价")
			.addAttribute("id", "p2")
			.addAttribute("name", "pfj")
			.addText("800") ;
		DOM4JUtils.writeBackXml(document, url) ;
	}
	
	/**
	* @Name: addSameLevelElement
	* @Description: 向指定元素节点下增加同级元素节点
	* 例如：
	* 	向第二本书节点的售价前增加内部价<内部价>200</内部价>
	* @Author: 李超	lc_jack@foxmail.com
	* @Version: V1.0
	* @CreateDate: 2017-2-26 下午4:39:08
	* @Parameters: 
	* @Return: void
	 */
	@Test
	public void addSameLevelElement() throws Exception {
		String url = "src/books.xml" ;
		Document document = DOM4JUtils.getDocument(url) ;
		Element secondBook = (Element) document.selectSingleNode("/书架/书[2]") ;
		Element innerPrice = DocumentHelper.createElement("内部价") ;
		innerPrice.addText("200") ;
		//向第二本书节点的售价前增加内部价<内部价>200</内部价>
		secondBook.elements().add(2, innerPrice) ;
		DOM4JUtils.writeBackXml(document, url) ;
	}
	
	/**
	* @Name: deleteElement
	* @Description: 删除指定元素节点：
	* 例如：
	* 	删除第二本书节点下的批发价节点
	* @Author: 李超	lc_jack@foxmail.com
	* @Version: V1.0
	* @CreateDate: 2017-2-26 下午4:43:55
	* @Parameters: 
	* @Return: void
	 */
	@Test
	public void deleteElement() throws Exception {
		String url = "src/books.xml" ;
		Document document = DOM4JUtils.getDocument(url) ;
		Element secondBook = (Element) document.selectSingleNode("/书架/书[2]") ;
		Element pfj = secondBook.element("批发价") ;
		//删除第二本书节点下的批发价节点
		secondBook.remove(pfj) ;
		DOM4JUtils.writeBackXml(document, url) ;
	}
	
	/**
	* @Name: opeElementAttribute
	* @Description: 操作节点属性
	* 例如：
	* 	添加：向第二本书节点上添加属性：bookid="a2"
	* 	删除：删除第二本书节点中批发价节点的name属性
	* 	修改：将第三本书节点的id属性改为：bookid="a33"
	* @Author: 李超	lc_jack@foxmail.com
	* @Version: V1.0
	* @CreateDate: 2017-2-26 下午4:46:59
	* @Parameters: 
	* @Return: void
	 */
	@Test
	public void opeElementAttribute() throws Exception {
		String url = "src/books.xml" ;
		Document document = DOM4JUtils.getDocument(url) ;
		//向第二本书节点上添加属性：bookid="a2"
		Element secondBook = (Element) document.selectSingleNode("//书[2]") ;
		secondBook.addAttribute("bookid", "a2") ;
		//删除批发价中的name属性
		Element pfj = secondBook.element("批发价") ;
		Attribute name = pfj.attribute("name") ;
		pfj.remove(name) ;
		//将第三本书节点的id属性改为：bookid="a33"
		Element thridBook = (Element) document.selectSingleNode("//书[3]") ;
		thridBook.setAttributeValue("bookid", "a33") ;
		DOM4JUtils.writeBackXml(document, url) ;
	}
	

}

